package games.mapacman.client;

import games.mapacman.common.Constants;
import games.mapacman.common.ZoneChangePoint;
import games.mapacman.server.MaPacmanRPWorld;

import java.util.Map;
import java.util.Vector;

import marauroa.client.net.IPerceptionListener;
import marauroa.common.Log4J;
import marauroa.common.game.RPObject;

class MaPacmanPerceptionListener implements IPerceptionListener {

    private static final marauroa.common.Logger logger = Log4J.getLogger(MaPacmanPerceptionListener.class);
    private Map<RPObject.ID, RPObject> wall_objects;
    private Vector<RPObject> ghosts;
    private Vector<RPObject> players;
    private GameScreen screen;
    private MaPacmanGui GUI;

    public MaPacmanPerceptionListener(Map<RPObject.ID, RPObject> game_walls,
            Vector<RPObject> game_ghosts, Vector<RPObject> game_players,
            GameScreen game_screen, MaPacmanGui game_GUI) {
        wall_objects = game_walls;
        ghosts = game_ghosts;
        players = game_players;
        screen = game_screen;
        GUI = game_GUI;
    }

    public boolean onMyRPObject(RPObject added, RPObject deleted) {
        return false;
    }

    public boolean onAdded(RPObject object) {
        try {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onAdded Object("
                    + object.getID() + ") added");
            

            if (object.get("type").equals(Constants.TYPE_GHOST)) {
                object.put("move", 0);
                object.put("imgCounter", 0);
                ghosts.add(object);
            } else if (object.get("type").equals(Constants.TYPE_DOT)
                    || object.get("type").equals(Constants.TYPE_SUPERDOT)
                    || object.get("type").equals(Constants.TYPE_FRUIT)
                    || object.get("type").equals(Constants.TYPE_POWERPILL)) {
                screen.addDot(object);
            } else if (object.get("type").equals(Constants.TYPE_PLAYER)) {
                object.put("move", 0);
                object.put("imgCounter", 0);
                players.add(object);
                if (object.get("name").equals(screen.getPlayerName())) {
                    screen.setPlayer(object);
                }
                if (object.has("text") && (object.get("text").length() > 0)) {
                    GUI.printText(object.get("name") + " : "
                            + object.get("text"));
                }
            } else if (object.get("type").equals(Constants.TYPE_WALL)) {
                if (!wall_objects.containsValue(object)) {
                    wall_objects.put(object.getID(), object);
                    screen.addWall(object.getInt("x"), object.getInt("y"));
                    screen.drawWall(object);
                }
            } else if (object.get("type").equals(Constants.TYPE_ZONECHANGE)) {
                screen.addZoneChange(new ZoneChangePoint(object));
            } else if (object.get("type").equals(Constants.TYPE_EATENSIGN)) {
                screen.addEatenSign(object);
            } else if (object.get("type").equals(Constants.TYPE_SCORESIGN)) {
                screen.addScoreSign(object);
            }
        } catch (Exception e) {
            logger.warn("MaPacman::MaPacmanPerceptionListener::onAdded " + object);
        }
        return false;
    }

    public boolean onModifiedAdded(RPObject object, RPObject changes) {
        // NOTE: We do handle the perception here ourselves. See that we return
        // true
        try {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onModifiedAdded Object("
                    + object.getID()
                    + ") modified in Game Objects container");

            object.applyDifferences(changes, null);

            if (object.get("type").equals(Constants.TYPE_GHOST)) {
                object.put("move", 0);
            } else if (object.get("type").equals(Constants.TYPE_DOT)
                    || object.get("type").equals(Constants.TYPE_SUPERDOT)
                    || object.get("type").equals(Constants.TYPE_FRUIT)
                    || object.get("type").equals(Constants.TYPE_POWERPILL)) {
                screen.addDot(object);
            } else if (object.get("type").equals(Constants.TYPE_PLAYER)) {
                // if (object.getInt("power")>0)
                // System.out.println("powermode");
                object.put("move", 0);
                if (object.has("text") && (object.get("text").length() > 0)) {
                    GUI.printText(object.get("name") + " : "
                            + object.get("text"));
                    /*
                     * if (!changes.get("zoneid").equals(object.get("zoneid")))
                     * players.remove(object);
                     */
                }
            } else if (object.get("type").equals(Constants.TYPE_WALL)) {
            }
        } catch (Exception e) {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onModifiedAdded "
                    + changes.toString());
            logger.warn("MaPacman::MaPacmanPerceptionListener::onModifiedAdded "
                    + e);
        }
        return false;
    }

    public boolean onModifiedDeleted(RPObject object, RPObject changes) {
        return false;
    }

    public boolean onDeleted(RPObject object) {

        Vector<RPObject> playersToRemove = new Vector<RPObject>();

        synchronized(players){
        for (RPObject player : players) {
                    if (player.getID().equals(object.getID())) {
                        playersToRemove.add(player);

                    }
                }
        }
        for (RPObject deletedPlayer : playersToRemove) {
            players.remove(deletedPlayer);
        }
        try {
            logger.debug("MaPacman::MaPacmanPerceptionListener::onDeleted Object("
                    + object
                    + ") removed from Static Objects container");

            if (object.get("type") == null) {
                return false;
            }
            if (object.get("type").equals(Constants.TYPE_PLAYER)) {
            } else if (object.get("type").equals(Constants.TYPE_EATENSIGN)) {
            } else if (object.get("type").equals(Constants.TYPE_GHOST)) {
            } else if (object.get("type").equals(Constants.TYPE_DOT)) {
            } else if (object.get("type").equals(Constants.TYPE_WALL)) {
            }
        } catch (Exception e) {
            logger.warn(object + " MaPacman::MaPacmanPerceptionListener::onDeleted" + players);
        }
        return false;
    }

    public void onSynced() {
        logger.debug("MaPacman::MaPacmanPerceptionListener::onSynced Synced with server state.");
    }

    public void onUnsynced() {
        logger.debug("MaPacman::MaPacmanPerceptionListener::onUnsynced Request resync");
        // resync();
    }

    public void onException(Exception e,
            marauroa.common.net.message.MessageS2CPerception perception) {
        logger.debug("MaPacman::MaPacmanPerceptionListener::onException "
                + perception.toString());
        logger.warn("MaPacman::MaPacmanPerceptionListener::onException " + e);
        System.exit(-1);
    }

    public boolean onClear() {
        logger.debug("MaPacman::MaPacmanPerceptionListener::onClear Clear!");
        return false;
    }

    public void onPerceptionBegin(byte type, int timestamp) {
        /*
         * logger.debug("MaPacman::MaPacmanPerceptionListener::onPerceptionBegin Params: "
         * + type + ", " + timestamp);
         */
    }

    public void onPerceptionEnd(byte type, int timestamp) {
        /*
         * logger.debug("MaPacman::MaPacmanPerceptionListener::onPerceptionEnd Params: "
         * + type + ", " + timestamp);
         */
    }
}
